home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 30 / Amiga Format AFCD30 (Sep 1998, Issue 114).iso / -seriously_amiga- / workbench / -datatypes- / mpegsystem / classbase.c < prev    next >
C/C++ Source or Header  |  1998-06-18  |  16KB  |  500 lines

  1.  
  2. /*
  3. **
  4. **  $VER: classbase.c 1.5 (1.6.98)
  5. **  mpegsystem.datatype 1.5
  6. **
  7. **  Library routines for a DataTypes class
  8. **
  9. **  Written 1997/1998 by Roland 'Gizzy' Mainz
  10. **  Original example source from David N. Junod
  11. **
  12. */
  13.  
  14.  
  15. /* main includes */
  16. #include "classbase.h"
  17.  
  18.  
  19. /****** mpegsystem.datatype/MAIN *********************************************
  20. *
  21. *    INTRODUCTION
  22. *        Datatypes class for MPEG 1 System movies (including VideCD streams)
  23. *
  24. *    REQUIREMENTS
  25. *        - You need at least Kick/WB 3.0.
  26. *
  27. *        - datatypes.library >= V45
  28. *
  29. *        - "datatypes/animation.datatype", >= V40.
  30. *          "animation.datatype 40.6 (28.09.93)" requires itself some
  31. *          libraries/boopsi classes:
  32. *          - "realtime.library", >= V39              - for timing
  33. *          - "gadgets/tapedeck.gadget" (any version) - for the controls
  34. *
  35. *        - mpegvideo.datatype >= V1.6 (V2.x preferred)
  36. *
  37. *        - mpegaudio.datatype >= V1.1
  38. *
  39. *    USAGE
  40. *        If the datatypes descriptor file was activated, any attempt to load
  41. *        a MPEG System stream using GMultiView, MultiView, AmigaGuide or
  42. *        SwitchWindow will load and play the movie.
  43. *
  44. *    INSTALLATION
  45. *        After unpacking this archive:
  46. *        Because this version does not include an Installer script, you have
  47. *        to do the installation manually through the shell:
  48. *
  49. *          - Unpack this archive and copy the "mpegsystem.datatype" to
  50. *            SYS:Classes/DataTypes/:
  51. *
  52. *        Copy CLONE FROM "mpegsystem.datatype" TO
  53. *         "SYS:Classes/DataTypes/mpegsystem.datatype"
  54. *
  55. *          - Then copy the datatypes descriptor into the DEVS:DataTypes
  56. *            directory.
  57. *            If the descriptor already exists, you should not replace it,
  58. *            otherwise you may loose "toolnodes" and other settings stored in
  59. *            the existing descriptor.
  60. *
  61. *     Copy CLONE FROM "MPEG System(%|.info)" TO DEVS:Datatypes/
  62. *
  63. *    SOURCE
  64. *        Source is included as an example how to write a datatypes clas
  65. *        implements a virtual filesystem and embeds other datatype objects
  66. *        for it's work.
  67. *
  68. *    MODEL
  69. *        This datatype uses a very complex model for decoding MPEG system
  70. *        streams. The small drawing below shows the model (OK, the
  71. *        drawing is not very good, it's incomplete and so on. If someone
  72. *        has the time to draw a better one, send it to me).
  73. *
  74. *                           system stream
  75. *                                 |
  76. *                                 |
  77. *                                 Y
  78. *             +-------------------------------------------------------------+
  79. *             |            mpeg system datatype                             |
  80. *             +-----------------------------------------+-------------------+
  81. *             |              demultiplexer              | ADTM_LOADFRAME    |
  82. *             |  video 0...video n | audio 0... audio n | ADTM_UNLOADFRAME  |
  83. *             +-----+-------+------+------+-------+-----+-------------------+
  84. *                   |       |             |       |               ^ ^
  85. *                   |       |             |       |               | |
  86. *                   |       *             |       *               | |
  87. *                   |                     |                       | |
  88. *                   |                     |                       | |
  89. *                   Y                     Y                       | |
  90. *      +---------------------+   +---------------------+          | |
  91. *      | mpeg video datatype |   | mpeg audio datatype |          | |
  92. *      +-----------+---------+   +--------+------------+          | |
  93. *                  |                      |                       | |
  94. *                  |                      |                       | |
  95. *                  |                      +-----------------------+ |
  96. *                  +------------------------------------------------+
  97. *
  98. *    AUTHOR
  99. *        If you want to blame me, report any bugs, or wants a new version
  100. *        send your letter to:
  101. *                        Roland Mainz
  102. *                        Hohenstaufenstraße 8
  103. *                        52388 Nörvenich
  104. *                        GERMANY
  105. *
  106. *        Phone: (+49)(0)2426/901568
  107. *        Fax:   (+49)(0)2426/901569
  108. *
  109. *        EMAIL is also available (if you want to send me attachments
  110. *        larger than 1MB (up to 5MB, more with my permission):
  111. *
  112. *        GISBURN@w-specht.rhein-ruhr.de
  113. *
  114. *        Up to August 1998 I'm reachable using this email address, too:
  115. *        Reinhold.A.Mainz@KBV.DE
  116. *
  117. *        | Please put your name and address in your mails !
  118. *        | German mailers should add their phone numbers.
  119. *        | See BUGS section above when submitting bug reports.
  120. *
  121. *        Sorry, but I can only look once a week for mails.
  122. *        If you don't hear something from me within three weeks, please
  123. *        send your mail again (but watch about new releases) (problems with
  124. *        this email port are caused by reconfigurations, hackers, network
  125. *        problems etc.).
  126. *
  127. *        The  entire  "mpegsystem.datatype"  package  may  be  noncommercially
  128. *        redistributed, provided  that  the package  is always  distributed
  129. *        in it's complete  form (including it's documentation). A small
  130. *        copy fee  for media costs is okay but any kind of commercial
  131. *        distribution is strictly forbidden without my permission !
  132. *        Comments and suggestions how to improve this program are
  133. *        generally appreciated!
  134. *
  135. *        Thanks to David Junod, who wrote the animation.datatype and lots of
  136. *        the datatypes example code, Matt Dillon for his DICE,
  137. *        Olaf 'Olsen' Barthel for his help, ideas and some text clips from
  138. *        his documentations.
  139. *
  140. ******************************************************************************
  141. *
  142. */
  143.  
  144.  
  145.  
  146. /****** mpegsystem.datatype/--datasheed-- ************************************
  147. *
  148. *   NAME
  149. *       mpegsystem.datatype -- data type for MPEG System streams
  150. *
  151. *   SUPERCLASS
  152. *       animation.datatype
  153. *
  154. *   DESCRIPTION
  155. *       The anim datatype, a sub-class of the animation.datatype, is used to
  156. *       load and play MPEG System movies.
  157. *
  158. *   METHODS
  159. *       OM_NEW -- Create a new animation object from a description file. The
  160. *           source may only be a file.
  161. *
  162. *       OM_DISPOSE -- Dispose instance and contents (embedded objects etc.
  163. *           etc.), then pass msg to superclass
  164. *
  165. *       OM_UPDATE -- Perform an ICM_CHECKLOOP check, and if succesfull, the
  166. *           method will be executed like OM_SET downstairs.
  167. *
  168. *       OM_SET -- Pass msg to superclass and call GM_RENDER if retval from
  169. *           superclass was != 0UL.
  170. *
  171. *       DTM_WRITE -- Save object's contents in local (MPEG System) or
  172. *           superclass (IFF ILBM) format.
  173. *           NOT IMPLEMENTED YET
  174. *
  175. *       ADTM_LOADFRAME -- Fill in struct adtFrame with requested information
  176. *           from embedded objects like bitmap, colormap and sample.
  177. *
  178. *       ADTM_UNLOADFRAME -- Free resources obtained by ADTM_UNLOADFRAME.
  179. *           The method is passed to the embedded objects.
  180. *
  181. *       All other methods are passed unchanged to superclass.
  182. *
  183. *   ATTRIBUTES
  184. *       Following attributes are set by the object and are READ-ONLY for
  185. *       applications:
  186. *
  187. *   BUGS
  188. *       - Support for streams with multiple video- and/or audio-streams
  189. *         has been removed. The datatype uses currently evertimes
  190. *         the first video- and the first audio-stream it finds.
  191. *
  192. *       - ADTM_START, ADT_PAUSE, ADTM_STOP and ADTM_LOCATE are not passed
  193. *         to the embedded mpevideo.datatype object(s), which may cause
  194. *         speed loss if this datatype does speed optimisations based on use
  195. *         of those methods.
  196. *
  197. *       - The sound may be out-of-sync in the case that a stream
  198. *         is very long (more than 60 minutes) due rounding problems.
  199. *         (In theory it should not occur - and I did not see the bug...).
  200. *
  201. *   TODO
  202. *       - Fixing the bugs above.
  203. *
  204. *       - Write the "--input_format--"-Autodoc section.
  205. *
  206. *       - Leading zeros in the beginning of the file except the "start code"
  207. *         begin sequence causes a stream not to be recognized by
  208. *         datatypes.library.
  209. *         May happen if someone reads raw data from a VideoCD.
  210. *
  211. *       - Writing the encoder part, using mpegvideo.datatype V2's encoder
  212. *         and mpegaudio.datatype's encoder parts.
  213. *
  214. *         Coming soon... :-)
  215. *
  216. *       - Implementation of ACTION_INFO in the internal filesystem that
  217. *         (in theory) optimized reading using async I/O gets correct
  218. *         parameters.
  219. *
  220. *       - Support for MPEG 2 system streams.
  221. *
  222. *       - QUICKSCAN option for optimized and much faster scanning of system
  223. *         streams.
  224. *
  225. *   HISTORY
  226. *       V1.1
  227. *         First public release.
  228. *
  229. *       V1.2
  230. *         - Fixed the descriptor (e.g. the file "MPEG System"). The
  231. *           old one contains unneccesary data in the comparisation mask.
  232. *           Now the descriptor matches the standard, except that
  233. *           leading zero bytes (0x00) causes that the stream won't be
  234. *           identified.
  235. *           Thanks to Steve Cutting (stevejc@c031aone.net.au) for reporting
  236. *           the bug.
  237. *           Fixed.
  238. *
  239. *         - Implemented IGNOREERRORS switch to get Steve Cutting's
  240. *           (stevejc@c031aone.net.au) example file
  241. *           "http://www.utexas.edustudents/cjso/Chabad/video/chase.mpg"
  242. *           working.
  243. *
  244. *         - Added missing VERBOSESYNTAX and DEBUG options to find problems
  245. *           in the datatype without recompiling the complete source.
  246. *
  247. *         - Fixed a bug in the FS:
  248. *           The internal filesystem now returns ERROR_SEEK_ERROR of someone
  249. *           send an ACTION_SEEK with an unknown position mode
  250. *           (e.g. if it is none of OFFSET_(BEGINNING|CURRENT|END)).
  251. *           Fixed.
  252. *
  253. *         - Fixed some problems with the VERBOSE and DEBUG output (missing
  254. *           newlines, single lines > 75 chars etc.).
  255. *           Fixed.
  256. *
  257. *       V1.3
  258. *         - Minor code cleanup
  259. *
  260. *         - Fixed and updated the autodoc.
  261. *
  262. *         - Increased the handlers process priority up to 9
  263. *           (normal FFS tasks are running at priority 10) to get more speed
  264. *           during scanning.
  265. *
  266. *       V1.4
  267. *         - Added asyncio.library support code (but it does not work yet...).
  268. *
  269. *         - Implemented ACTION_COPY_DIR_FH to get DupLockFromFH working which
  270. *           is used in the new mpegaudio.datatype V2 (currently this feature
  271. *           is not used because of some problems with mpega.library, but...).
  272. *
  273. *         - Fixed a bug in OM_NEWs state machine which caused big problems
  274. *           if an error occurs with IoErr() == 0.
  275. *           Fixed.
  276. *
  277. *       V1.5
  278. *         - Removed non-working asyncio.library support code.
  279. *
  280. *         - Implemented my own "async" dos packet system, which is more
  281. *           efficient than asyncio.library's one (in our case !).
  282. *
  283. *         - Added/removed/moved some code to get rid of a "Seek" in the 
  284. *           scan phase.
  285. *
  286. *         - Added some usefull comments.
  287. *
  288. *         - Moved preferences support code into "prefs.c".
  289. *
  290. *         - Implemented NOVERBOSE option as requested by many people.
  291. *
  292. *         - Increased handlers priority to 15 and renamed the hander's
  293. *           process.
  294. *
  295. *   SEE ALSO
  296. *       animation.datatype,
  297. *       anim.datatype,
  298. *       gifanim.datatype,
  299. *       mpegvideo.datatype, mpegaudio.datatype,
  300. *       picmovie.datatype,
  301. *       cdxl.datatype, avi.datatype, quicktime.datatype,
  302. *       moviesetter.datatype,
  303. *       film.datatype,
  304. *       directory.datatype,
  305. *       markabletextdtclass
  306. *
  307. *******************************************************************************
  308. *
  309. */
  310.  
  311.  
  312. /****** mpegsystem.datatype/--input_format-- *********************************
  313. *
  314. *    NAME
  315. *        MPEG System -- MPEG System stream format
  316. *
  317. *    DESCRIPTION
  318. *        <Not written yet, sorry>
  319. *
  320. *    SEE ALSO
  321. *
  322. *******************************************************************************
  323. *
  324. */
  325.  
  326.  
  327.  
  328. /*****************************************************************************/
  329.  
  330. DISPATCHERFLAGS
  331. struct IClass *ObtainMPEGSystemEngine( REGA6 struct ClassBase *cb )
  332. {
  333.     return( (cb -> cb_Lib . cl_Class) );
  334. }
  335.  
  336. /*****************************************************************************/
  337.  
  338. DISPATCHERFLAGS
  339. struct Library *LibInit( REGD0 struct ClassBase *cb, REGA0 BPTR seglist, REGA6 struct ExecBase *sysbase )
  340. {
  341.     cb -> cb_SegList = seglist;
  342.     cb -> cb_SysBase = sysbase;
  343.  
  344.     InitSemaphore( (&(cb -> cb_Lock)) );
  345.  
  346.     /* Kickstart V3.0 ? */
  347.     if( (cb -> cb_SysBase -> LibNode . lib_Version) >= 39UL )
  348.     {
  349.       /* Obtain ROM libs */
  350.       if( cb -> cb_UtilityBase = OpenLibrary( "utility.library", 39UL ) )
  351.       {
  352.         if( cb -> cb_DOSBase = OpenLibrary( "dos.library", 39UL ) )
  353.         {
  354.           if( cb -> cb_GfxBase = OpenLibrary( "graphics.library", 39UL ) )
  355.           {
  356.             if( cb -> cb_IntuitionBase = OpenLibrary( "intuition.library", 39UL ) )
  357.             {
  358.               return( (&(cb -> cb_Lib . cl_Lib)) );
  359.  
  360. #ifdef COMMENTED_OUT
  361.               CloseLibrary( (cb -> cb_IntuitionBase) );
  362. #endif /* COMMENTED_OUT */
  363.             }
  364.  
  365.             CloseLibrary( (cb -> cb_GfxBase) );
  366.           }
  367.  
  368.           CloseLibrary( (cb -> cb_DOSBase) );
  369.         }
  370.  
  371.         CloseLibrary( (cb -> cb_UtilityBase) );
  372.       }
  373.     }
  374.  
  375.     return( NULL );
  376. }
  377.  
  378. /*****************************************************************************/
  379.  
  380. DISPATCHERFLAGS
  381. LONG LibOpen( REGA6 struct ClassBase *cb )
  382. {
  383.     LONG retval = (LONG)cb;
  384.     BOOL success = TRUE;
  385.  
  386.     ObtainSemaphore( (&(cb -> cb_Lock)) );
  387.  
  388.     /* Use an internal use counter */
  389.     cb -> cb_Lib . cl_Lib . lib_OpenCnt++;
  390.     cb -> cb_Lib . cl_Lib . lib_Flags &= ~LIBF_DELEXP;
  391.  
  392.     if( (cb -> cb_Lib . cl_Lib . lib_OpenCnt) == 1U )
  393.     {
  394.       if( (cb -> cb_Lib . cl_Class) == NULL )
  395.       {
  396.         success = FALSE;
  397.  
  398.         /* Only datatypes.library >= V45 supports virtual handlers... */
  399.         if( cb -> cb_DataTypesBase = OpenLibrary( "datatypes.library", 45UL ) )
  400.         {
  401.           /* Should require animation.datatype V41 */
  402.           if( cb -> cb_SuperClassBase = OpenLibrary( "datatypes/animation.datatype", 39UL /*41UL*/ ) )
  403.           {
  404.             if( cb -> cb_Lib . cl_Class = initClass( cb ) )
  405.             {
  406.               success = TRUE;
  407.             }
  408.           }
  409.         }
  410.       }
  411.     }
  412.  
  413.     if( !success )
  414.     {
  415.       CloseLibrary( (cb -> cb_SuperClassBase) );
  416.       CloseLibrary( (cb -> cb_DataTypesBase) );
  417.  
  418.       cb -> cb_DataTypesBase = cb -> cb_SuperClassBase = NULL;
  419.  
  420.       (cb -> cb_Lib . cl_Lib . lib_OpenCnt)--;
  421.  
  422.       retval = 0L;
  423.     }
  424.  
  425.     ReleaseSemaphore( (&(cb -> cb_Lock)) );
  426.  
  427.     return( retval );
  428. }
  429.  
  430. /*****************************************************************************/
  431.  
  432. DISPATCHERFLAGS
  433. LONG LibClose( REGA6 struct ClassBase *cb )
  434. {
  435.     LONG retval = 0L;
  436.  
  437.     ObtainSemaphore( (&(cb -> cb_Lock)) );
  438.  
  439.     if( cb -> cb_Lib . cl_Lib . lib_OpenCnt )
  440.     {
  441.       (cb -> cb_Lib . cl_Lib . lib_OpenCnt)--;
  442.     }
  443.  
  444.     if( ((cb -> cb_Lib . cl_Lib . lib_OpenCnt) == 0U) && (cb -> cb_Lib . cl_Class) )
  445.     {
  446.       if( FreeClass( (cb -> cb_Lib . cl_Class) ) )
  447.       {
  448.         cb -> cb_Lib . cl_Class = NULL;
  449.  
  450.         CloseLibrary( (cb -> cb_SuperClassBase) );
  451.         CloseLibrary( (cb -> cb_DataTypesBase) );
  452.       }
  453.       else
  454.       {
  455.         cb -> cb_Lib . cl_Lib . lib_Flags |= LIBF_DELEXP;
  456.       }
  457.     }
  458.  
  459.     ReleaseSemaphore( (&(cb -> cb_Lock)) );
  460.  
  461.     if( (cb -> cb_Lib . cl_Lib . lib_Flags) & LIBF_DELEXP )
  462.     {
  463.       retval = LibExpunge( cb );
  464.     }
  465.  
  466.     return( retval );
  467. }
  468.  
  469. /*****************************************************************************/
  470.  
  471. DISPATCHERFLAGS
  472. LONG LibExpunge( REGA6 struct ClassBase *cb )
  473. {
  474.     BPTR seg;
  475.  
  476.     if( cb -> cb_Lib . cl_Lib . lib_OpenCnt )
  477.     {
  478.       cb -> cb_Lib . cl_Lib . lib_Flags |= LIBF_DELEXP;
  479.  
  480.       seg = NULL;
  481.     }
  482.     else
  483.     {
  484.       Remove( (&(cb -> cb_Lib . cl_Lib . lib_Node)) );
  485.  
  486.       seg = cb -> cb_SegList;
  487.  
  488.       CloseLibrary( (cb -> cb_IntuitionBase) );
  489.       CloseLibrary( (cb -> cb_GfxBase) );
  490.       CloseLibrary( (cb -> cb_DOSBase) );
  491.       CloseLibrary( (cb -> cb_UtilityBase) );
  492.  
  493.       FreeMem( (APTR)((ULONG)(cb) - (ULONG)(cb -> cb_Lib . cl_Lib . lib_NegSize)), (ULONG)((cb -> cb_Lib . cl_Lib . lib_NegSize) + (cb -> cb_Lib . cl_Lib . lib_PosSize)) );
  494.     }
  495.  
  496.     return( (LONG)seg );
  497. }
  498.  
  499.  
  500.